package com.hkj.configcenter.core.utils;

import com.github.zkclient.ZkClient;
import com.hkj.configcenter.core.Context;
import com.hkj.configcenter.core.processor.ZkProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class ZkUtils {

    public static ZkClient getConnection(String zkUrl) {
        try {
            ZkClient zkClient = new ZkClient(zkUrl);
            zkClient.waitUntilConnected();
            return zkClient;
        } catch (Throwable e) {
            log.error("【配置中心】 - Zookeeper连接失败 - 请检查参数是否正确 --> {}", zkUrl, e);
            throw new IllegalArgumentException("【配置中心】 - Zookeeper连接失败 - 请检查参数是否正确 --> " + zkUrl, e);
        }
    }

    public static Map<String, String> getChildrenValue(ZkClient zkClient, String path) {

        Map<String, String> map = new HashMap<String, String>();

        List<String> checkList = new ArrayList<String>();

        getChildrenValue(zkClient, path, map, checkList);

        return map;
    }

    private static void getChildrenValue(ZkClient zkClient, String parentPath, Map<String, String> map, List<String> checkList) {
        List<String> children = zkClient.getChildren(parentPath);
        if (children.size() > 0) {
            for (String child : children) {
                getChildrenValue(zkClient, parentPath + "/" + child, map, checkList);
            }
        } else {
            String value = readData(zkClient, parentPath);
            if (value != null) {
                String paramName = ZkProcessor.getKey(parentPath);
                if (checkList.contains(paramName)) {
                    throw new IllegalArgumentException("【配置中心】  - 重复参数 ==> " + paramName);
                }
                checkList.add(paramName);
                map.put(parentPath, readData(zkClient, parentPath));
            }
        }
    }

    public static void getChildrenValue(ZkClient zkClient, String parentPath, StringBuffer buffer) {

        if (parentPath.contains(Context.ONLINE_MACHINES)) {
            return;
        }

        List<String> children = zkClient.getChildren(parentPath);

        if (children.size() > 0) {

            buffer.append(parentPath).append("=").append(readData1(zkClient, parentPath)).append("\n");

            for (String child : children) {
                getChildrenValue(zkClient, parentPath + "/" + child, buffer);
            }

        } else {

            buffer.append(parentPath).append("=").append(readData1(zkClient, parentPath)).append("\n");

        }

    }

    public static String readData(ZkClient zkClient, String path) {
        try {
            if (zkClient.exists(path)) {
                byte[] bs = zkClient.readData(path);
                if (bs != null) {
                    return new String(bs, "UTF-8");
                }
            }
            return null;
        } catch (Throwable e) {
            throw new IllegalArgumentException("【配置中心】 - Zookeeper读取数据异常 - path --> " + path, e);
        }
    }

    public static String readData1(ZkClient zkClient, String path) {
        String data = readData(zkClient, path);
        return data == null ? "" : data;
    }

    public static String[] readTextRemark(String path) {
        String data = readData(Context.zkClient, path);
        if (data == null || data.trim().equals(Context.SPLIT_FLAG)) {
            return new String[]{"", ""};
        }

        String[] values = data.split(Context.SPLIT_FLAG);
        return values.length > 1 ? values : new String[]{values[0], ""};
    }

    public static String exportTextRemark(String path) {
        String data = ZkUtils.readData1(Context.zkClient, path);
        if (StringUtils.isEmpty(data)) {
            return "";
        }

        String[] value_desc = data.split(Context.SPLIT_FLAG);
        if (value_desc.length <= 0) {
            return "";
        }

        String text = value_desc[0].replaceAll("[\\n\\r]", "").trim();
        String remark = (value_desc.length > 1 ? Context.SPLIT_FLAG + value_desc[1].replaceAll("[\\n\\r]", Context.LINE_FEED) : "");
        return text + remark;
    }

    public static String getVersionValue(String version) {
        try {
            return new String(InetAddress.getLocalHost().getHostAddress()) + " : v" + version;
        } catch (Exception e) {
            throw new IllegalArgumentException("【配置中心】 - 获取本地ip地址异常", e);
        }
    }

    public static String getEnvByPath(String url) {
        return url.split("/")[2];
    }

}
